﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DataFeedService
{
    class DataSource : IDataSource
    {
        private IList<IObserver<TickUpdate>> observers;

        private Random rand;

        private Timer timer;

        #region Unsubscriber
        private class Unsubscriber : IDisposable
        {
            private IList<IObserver<TickUpdate>> observers;
            private IObserver<TickUpdate> observer;

            public Unsubscriber(IList<IObserver<TickUpdate>> observers, IObserver<TickUpdate> observer)
            {
                this.observers = observers;
                this.observer = observer;
            }

            public void Dispose()
            {
                if (!(observer == null)) observers.Remove(observer);
            }
        }
        #endregion

        public DataSource()
        {
            observers = new List<IObserver<TickUpdate>>();

            rand = new Random(DateTime.Now.Millisecond);

            timer = new Timer(o =>
            {
                TickUpdate update = new TickUpdate(rand.Next(), DateTime.Now);

                Parallel.ForEach<IObserver<TickUpdate>>(observers, observer =>
                {
                    observer.OnNext(update);
                });
            }, null, 0, 1000);
        }

        public void Start()
        {
            try
            {
                timer.Change(0, 250);
            }
            catch { throw; }
        }

        public void Stop()
        {
            try
            {
                timer.Change(Timeout.Infinite, 250);
            }
            catch { throw; }
        }

        public IDisposable Subscribe(IObserver<TickUpdate> observer)
        {
            if (!observers.Contains(observer))
                observers.Add(observer);

            return new Unsubscriber(observers, observer);
        }
    }
}
